/* 
 * File:	main.c
 * Authors: Johan Dahlberg <S102591>
 *				Daniel Jansson <S102496>
 * ---------------------------------
 * Task 4a: This program solves a maze by recursive backtracking.
 */
#include <stdio.h>
#include "genlib.h"
#include "mazelib.h"
#include "simpio.h"

/*
 * Constants
 * ---------
 * MazeFile -- Name of the file containing the maze
 */
//#define MazeFile "pathlen.maz"
#define NoSolution 10000

static int SolveMaze(pointT pt,int shortest,int nMarks);
static pointT AdjacentPoint(pointT pt, directionT dir);
static int sShortestPathLength(pointT pt,int *nMarks);

static int ShortestPathLength(pointT pt);

/* Code */
main() {
   string MazeFile;
	int shortestPath;
	int *prefix;
	
	prefix = NewArray(1,int);
	prefix[0] = 0;
	prefix[1] = 0;
	
	printf("Please input the file you want to read from\n");
	MazeFile = GetLine();
	
	ReadMazeMap(MazeFile);
	
	prefix = ShortestPathLength(GetStartPosition(), prefix);
	shortestPath = prefix[1];
	
	if(shortestPath != NoSolution) {
		printf("The shortest path is: %d\n",shortestPath);
	} else {
		printf("There is no solution to this maze\n");
	}
}

/*
 * Function: ShortestPathLength
 * Usage: shortestPath = ShortestPathLength(pt, *nMarks);
 * --------------------------------------
 * Return the smallest path
 */
static int ShortestPathLength(pointT pt,int *nMarks) {
	directionT dir;
	directionT tempDir;
	int temp;
	
	temp = nMarks[1];
	if (IsMarked(pt)) {
		return (pt,nMarks);
	}
	
	nMarks[0]++;
	
	MarkSquare(pt);
   for (dir = North; dir <= West; dir++) {
		if (!WallExists(pt, dir)) {
			if (OutsideMaze(AdjacentPoint(pt, dir))) {
				if(nMarks[0] < nMarks[1] || nMarks[1] == 0) {
					nMarks[1] = nMarks[0];
					UnmarkSquare(pt);
					return(pt,nMarks);
				}
			} else {
				nMarks = ShortestPathLength(AdjacentPoint(pt, dir),nMarks);
			}
		}
    }

	nMarks[0]--;
   UnmarkSquare(pt);
	temp = nMarks[1];
	
	return pt, nMarks;
}

/*
 * Function: returnMin
 * Usage: min = returnMin(a, b);
 * --------------------------------------
 * Return the smallest number of two int
 */
static int returnMin(int a, int b) {
	if(a == 0) {
		return(b);
	}

	if(a<b) {
		return(a);
	}
}

/*
 * Function: AdjacentPoint
 * Usage: newpt = AdjacentPoint(pt, dir);
 * --------------------------------------
 * This function returns the pointT that results from moving
 * one square from pt in the direction specified by dir.  For
 * example, if pt is the point (1,1), AdjacentPoint(pt, East)
 * would return the point (2,1).
 */
static pointT AdjacentPoint(pointT pt, directionT dir) {
    pointT newpt;

    newpt = pt;
    switch (dir) {
      case North: newpt.y++; break;
      case East:  newpt.x++; break;
      case South: newpt.y--; break;
      case West:  newpt.x--; break;;
    }

    return newpt;
}